package cn.wen.yinxiu.works.service.impl;

import cn.wen.yinxiu.common.enums.DelEnum;
import cn.wen.yinxiu.common.enums.StatusEnum;
import cn.wen.yinxiu.common.to.es.TopicEsModel;
import cn.wen.yinxiu.common.to.works.TopicTO;
import cn.wen.yinxiu.common.toolkit.DateUtils;
import cn.wen.yinxiu.works.feign.SearchFeignService;
import cn.wen.yinxiu.works.vo.TopicInfoVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yinxiu.common.toolkit.PageUtils;
import cn.wen.yinxiu.common.toolkit.Query;

import cn.wen.yinxiu.works.dao.TopicDao;
import cn.wen.yinxiu.works.entity.TopicEntity;
import cn.wen.yinxiu.works.service.TopicService;

@Component
@Service("topicService")
public class TopicServiceImpl extends ServiceImpl<TopicDao, TopicEntity> implements TopicService {

    @Autowired
    private TopicDao topicDao;

    @Autowired
    private SearchFeignService searchFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<TopicEntity> page = this.page(
                new Query<TopicEntity>().getPage(params),
                new QueryWrapper<TopicEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<TopicInfoVO> queryWorksTopicList(Long worksId) {
        return topicDao.selectWorksTopicList(worksId);
    }

    @Override
    public void saveTopicAndWorksRelation(List<Long> topicIds, Long worksId) {
        topicDao.saveTopicAndWorksIdRelation(topicIds, worksId);
    }

    @Override
    public void updateTopicAndWorksRelation(Long worksId, String[] topicTitles) {
        // 1.先删除对应的话题
        topicDao.deleteTopicAndWorksRelation(worksId);
        // 2.添加对应的话题
        // 2.1.实现需要通过标题列表获取topicIds
        List<TopicEntity> topicEntityList = getTopicListByTitle(topicTitles);
        // 2.2.插入数据库不存在的
        List<Long> exitList = new ArrayList<>();
        List<String> exitTitleList = new ArrayList<>();
        topicEntityList.stream().forEach(item -> {
            if (item.getStatus() == StatusEnum.NORMAL_USE.code()) {
                exitList.add(item.getTopicId());
                exitTitleList.add(item.getTopicTitle());
            }
        });
        // 求出需要存储的差集
        List<String> topicList = Arrays.asList(topicTitles);
        topicList.removeAll(exitTitleList);
        // 插入数据
        List<Long> list = saveTopicByList(topicList);
        exitList.addAll(list);
        // 3.3.关联话题&作品
        saveTopicAndWorksRelation(exitList, worksId);
    }

    private List<Long> saveTopicByList(List<String> topicList) {
        List<TopicEntity> collect = topicList.stream().map(item -> {
            TopicEntity target = new TopicEntity();
            target.setStatus(StatusEnum.NORMAL_USE.code());
            target.setIsDeleted(DelEnum.NORMAL.code());
            target.setTopicTitle(item);
            return target;
        }).collect(Collectors.toList());
        this.saveBatch(collect);
        return collect.stream().map(item -> {
            return item.getTopicId();
        }).collect(Collectors.toList());
    }

    private List<TopicEntity> getTopicListByTitle(String[] topicTitles) {
        QueryWrapper<TopicEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        queryWrapper.in("topic_title", topicTitles);
        return topicDao.selectList(queryWrapper);
    }

    @Override
    public List<TopicInfoVO> queryTopicHotList() {
        QueryWrapper<TopicEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        // 最近15天的高热度
        String pastDate = DateUtils.getPastDate(15, "yyyy-MM-dd hh:mm:ss");
        queryWrapper.ge("create_time", pastDate);
        queryWrapper.orderByDesc("topic_view");
        queryWrapper.last("LIMIT 20");
        List<TopicEntity> topicList = topicDao.selectList(queryWrapper);
        List<TopicInfoVO> resList = topicList.stream().map(item -> {
            TopicInfoVO target = new TopicInfoVO();
            BeanUtils.copyProperties(item, target);
            return target;
        }).collect(Collectors.toList());
        return resList;
    }

    @Override
    public boolean updateTopicViewList(List<TopicTO> topicList) {
        return topicDao.updateTopicViewList(topicList);
    }

    @Override
    public List<TopicInfoVO> searchTopicList(String keyword) {
        QueryWrapper<TopicEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        queryWrapper.likeRight("topic_title", keyword);
        queryWrapper.orderByDesc("topic_view");
        queryWrapper.last("LIMIT 15");
        List<TopicEntity> topicEntities = topicDao.selectList(queryWrapper);
        List<TopicInfoVO> resList = topicEntities.stream().map(item -> {
            TopicInfoVO target = new TopicInfoVO();
            BeanUtils.copyProperties(item, target);
            return target;
        }).collect(Collectors.toList());
        return resList;
    }

    @Override
    public List<String> queryTopicTitleByIds(List<Long> topicIdList) {
        QueryWrapper<TopicEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        if (topicIdList != null || topicIdList.size() != 0) {
            queryWrapper.in("topic_id", topicIdList);
        }
        List<TopicEntity> topicEntityList = topicDao.selectList(queryWrapper);
        if (topicEntityList == null) return new ArrayList<>();
        return topicEntityList.stream().map(item -> {
            return item.getTopicTitle();
        }).collect(Collectors.toList());
    }

    @Override
    public List<TopicEsModel> getTopicGuessSearch(String keyword) {
        return searchFeignService.searchGuessTopic(keyword).getData();
    }
}